package com.crazy.mybatis.gerenator.service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.crazy.mybatis.gerenator.service.common.Constants;
import com.crazy.mybatis.gerenator.service.common.ElementName;
import com.crazy.mybatis.gerenator.service.common.MethodEnum;
import com.crazy.mybatis.gerenator.service.java.BeanFileWriter;
import com.crazy.mybatis.gerenator.service.java.ClassMetaData;
import com.crazy.mybatis.gerenator.service.java.JavaBuilder;
import com.crazy.mybatis.gerenator.service.java.MapperFileWriter;
import com.crazy.mybatis.gerenator.service.xml.CustomXmlWriter;
import com.crazy.mybatis.gerenator.service.xml.ElementBuiderFactory;
import com.crazy.mybatis.gerenator.service.xml.ElementBuilder;

@Component
public class DefaultGenerator implements Generator {

	private Document document;

	@Autowired
	private Context context;

	@Autowired
	private ElementBuilder resultMapBuilder;

	@Autowired
	private ElementBuilder baseColumnBuilder;
	
	@Autowired
	private JavaBuilder javaBuilder;
	
	public DefaultGenerator() {
		this.document = DocumentHelper.createDocument();
		document.addDocType("mapper",
				"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd", null);
	}

	@Override
	public void generate() {
		// TODO: 根据context生成document
		Element mapper = DocumentHelper.createElement(ElementName.MAPPER);
		mapper.addAttribute("namespace", context.getMapperPackage() + "." + context.getBeanName() + "Mapper");
		document.setRootElement(mapper);
		
		mapper.add(resultMapBuilder.build(context));
		mapper.add(baseColumnBuilder.build(context));
		
		if (context.getMethodSet().contains(MethodEnum.INSERT)) {
			mapper.add(ElementBuiderFactory.getBuidler("insertBuilder").build(context));
		}
		if (context.getMethodSet().contains(MethodEnum.INSERT_SELECTIVE)) {
			mapper.add(ElementBuiderFactory.getBuidler("insertSelectiveBuilder").build(context));
		}
		if (context.getMethodSet().contains(MethodEnum.UPDATE_BY_PRIMARY_KEY_SELECTIVE)) {
			mapper.add(ElementBuiderFactory.getBuidler("updateSelectiveBuilder").build(context));
		}

		OutputFormat format = new OutputFormat();
		format.setTrimText(false);
		format.setNewlines(true);
		format.setIndent(Constants.INTENT);
		format.setEncoding(Constants.UTF8);// 设置编码格式
		CustomXmlWriter xmlWriter = null;
		try {
			xmlWriter = new CustomXmlWriter(new FileOutputStream("D:\\" + context.getBeanName() + "Mapper.xml"), format);
			xmlWriter.setEscapeText(false);
			xmlWriter.write(document);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (xmlWriter != null) {
				try {
					xmlWriter.close();
				} catch (IOException e) {

				}
			}
		}
		
		
		// write java
		ClassMetaData meta = javaBuilder.build(context);
		FileWriter fw = null;
		try {
			fw = new FileWriter(new File("D:\\" + meta.getClassName()) + ".java");
			BeanFileWriter writer = new BeanFileWriter(fw);
			writer.write(meta);
			
			
			ClassMetaData mMeta = javaBuilder.buildMethodMeta(context);
			String mapperFile = "D:\\" + context.getBeanName() + "Mapper.java";
			FileWriter fw2 = new FileWriter(new File(mapperFile));
			MapperFileWriter mwriter = new MapperFileWriter(fw2);
			mwriter.write(mMeta);
			fw2.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
